package com.yq.cp.controller.basics;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yq.cp.config.MyException;
import com.yq.cp.config.UserThreadLocal;
import com.yq.cp.entity.basics.*;
import com.yq.cp.entity.basics.model.SiteHeaderToUser;
import com.yq.cp.entity.basics.model.StructureTree;
import com.yq.cp.entity.basics.model.UserToStructureModel;
import com.yq.cp.entity.common.ApiResult;
import com.yq.cp.entity.common.PageVo;
import com.yq.cp.entity.permission.User;
import com.yq.cp.entity.permission.dto.UserDto;
import com.yq.cp.entity.permission.vo.UserVo;
import com.yq.cp.mapper.basics.AreasMapper;
import com.yq.cp.mapper.basics.CitiesMapper;
import com.yq.cp.mapper.basics.ProvincesMapper;
import com.yq.cp.service.basics.*;
import com.yq.cp.service.permission.UserService;
import com.yq.cp.service.yw.YwZbglService;
import com.yq.cp.utils.DateTimeUtil;
import com.yq.cp.utils.MD5Util;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织架构 前端控制器
 * </p>
 *
 * @author shenyuqing
 * @since 2024-08-27
 */
@RestController
@RequestMapping("/organizationalStructure")
public class OrganizationalStructureController {
    @Resource
    OrganizationalStructureService organizationalStructureService;
    @Resource
    UserService userService;
    @Resource
    AreaService areaService;
    @Resource
    YwZbglService ywZbglService;
    @Resource
    ProvincesMapper provincesMapper;
    @Resource
    CitiesMapper citiesMapper;
    @Resource
    AreasMapper areasMapper;
    @Resource
    DepartmentService departmentService;
    @Resource
    EquipmentManagementService equipmentManagementService;
    /**
     * 渠道商添加
     * @param vo
     * @return
     */
    @PostMapping("channelAdds")
    public ApiResult add(@RequestBody OrganizationalStructure vo){
        organizationalStructureService.add(vo);
        return ApiResult.success();
    }

    /**
     *  渠道商审核列表
     * @return
     */
    @PostMapping("channelExamineListevery")
    public ApiResult channelExamineList(@RequestBody PageVo vo){
        IPage<UserToStructureModel> page =  organizationalStructureService.channelExamineList(vo);
        return ApiResult.success(page);
    }

    /**
     * 渠道商审核
     * @param vo
     * @return
     */
    @PostMapping("channelExamine")
    public ApiResult channelExamine(@RequestBody OrganizationalStructure vo) throws InterruptedException {
        User user = UserThreadLocal.get();
        vo.setExaminePersonName(user.getUsername());
        vo.setExamineTime(DateTimeUtil.dqsj());
        vo.setExaminePersonSignature(user.getElectronicSignature());
        organizationalStructureService.saveOrUpdate(vo);
        List<OrganizationalStructure> list = organizationalStructureService.list(new QueryWrapper<OrganizationalStructure>()
                .eq("channel_id", vo.getId()));

        ExecutorService executor = Executors.newFixedThreadPool(list.size()); // 创建线程池
        try {
            // 提交任务
            for (final OrganizationalStructure organizationalStructure : list) {
                executor.submit(new Callable<Object>() {
                    @Override
                    public Object call() throws Exception {
                        organizationalStructure.setExamine(vo.getExamine());
                        organizationalStructureService.saveOrUpdate(organizationalStructure);
                        return null;
                    }
                });
            }
        } finally {
            executor.shutdown(); // 关闭线程池
            executor.awaitTermination(10, TimeUnit.SECONDS); // 等待所有任务完成
        }

//        for (OrganizationalStructure organizationalStructure : list) {
//            organizationalStructure.setExamine(vo.getExamine());
//            organizationalStructureService.saveOrUpdate(organizationalStructure);
//        }
        User structure_id = userService.getOne(new QueryWrapper<User>()
                .eq("structure_id", vo.getId()));
        structure_id.setExamine(vo.getExamine());
        userService.saveOrUpdate(structure_id);
        return ApiResult.success();
    }

    /**
     * 编辑/重新提交
     * @param vo
     * @return
     */
    @PostMapping("channelEdit")
    public ApiResult channelEdit(@RequestBody OrganizationalStructure vo){
        organizationalStructureService.channelEdit(vo);
        return ApiResult.success();
    }

    /**
     * 渠道商删除
     * @param vo
     * @return
     */
    @PostMapping("channelRemove")
    public ApiResult channelRemove(@RequestBody OrganizationalStructure vo){
        List<OrganizationalStructure> list = organizationalStructureService.list(new QueryWrapper<OrganizationalStructure>().eq("channel_id", vo.getId()));
        if (!list.isEmpty()){
            List<Long> collect = list.stream().map(OrganizationalStructure::getId).collect(Collectors.toList());
                List<User> list1 = userService.list(new QueryWrapper<User>()
                        .eq("examine", 1)
                        .in("structure_id", collect));
                if (!list1.isEmpty())
                    throw new MyException("该渠道商下面还有关联数据，请清理后再试！！！");
        }
        userService.remove(new QueryWrapper<User>()
                .eq("structure_id",vo.getId()));
        organizationalStructureService.removeById(vo);
        organizationalStructureService.removeByIds(list);
        return ApiResult.success();
    }

    /**
     * 站点添加
     * @param vo
     * @return
     */
    @PostMapping("siteAdd")
    public ApiResult siteAdd(@RequestBody OrganizationalStructure vo) {
        vo.setExamine(0);
        vo.setType(6);
        if (!Objects.isNull(vo.getChannelId())) {
            OrganizationalStructure byId = organizationalStructureService.getById(vo.getChannelId());
            vo.setChannelName(byId.getName());
        }
        if (!Objects.isNull(vo.getRegionId())) {
            OrganizationalStructure byId = organizationalStructureService.getById(vo.getRegionId());
            vo.setRegionName(byId.getName());
        }
        if (!Objects.isNull(vo.getShengId())) {
            OrganizationalStructure byId = organizationalStructureService.getById(vo.getShengId());
            vo.setShengName(byId.getName());
        }
        if (!Objects.isNull(vo.getShiId())) {
            OrganizationalStructure byId = organizationalStructureService.getById(vo.getShiId());
            vo.setShiName(byId.getName());
        }
        if (!Objects.isNull(vo.getQuId())) {
            OrganizationalStructure byId = organizationalStructureService.getById(vo.getQuId());
            vo.setQuName(byId.getName());
        }

        vo.setBelongingRegion(vo.getShengName()+vo.getShiName()+vo.getQuName());
        organizationalStructureService.saveOrUpdate(vo);
        return ApiResult.success();
    }

    /**
     * 站点管理/站点审核列表/删除列表
     * @param vo
     * @return
     * state 0-站点管理  1-站点审核列表 2-删除列表
     */
    @PostMapping("siteListgai")
    public ApiResult siteList(@RequestBody PageVo vo) {
        IPage<OrganizationalStructure> page =  organizationalStructureService.siteList(vo);
        return ApiResult.success(page);
    }

    /**
     * 站点审核
     * @param vo
     * @return
     */
    @PostMapping("siteExamine")
    public ApiResult siteExamine(@RequestBody OrganizationalStructure vo) {
        User user = UserThreadLocal.get();
        vo.setExaminePersonId(user.getId());
        vo.setExaminePersonName(user.getNickname());
        vo.setExamineTime(DateTimeUtil.dqsj());
        vo.setExaminePersonSignature(user.getElectronicSignature());
        organizationalStructureService.saveOrUpdate(vo);
        if (vo.getExamine()==1){
            ywZbglService.add(vo);
        }
        return ApiResult.success();
    }

    /**
     * 站点编辑/重新提交
     * @param vo
     * @return
     */
    @PostMapping("siteEdit")
    public ApiResult siteEdit(@RequestBody OrganizationalStructure vo) {
        vo.setBelongingRegion(vo.getShengName()+vo.getShiName()+vo.getQuName());
        organizationalStructureService.saveOrUpdate(vo);
        return ApiResult.success();
    }

    /**
     * 站点删除-改状态
     * @param vo
     * @return
     */
    @PostMapping("siteRemove")
    public ApiResult siteRemove(@RequestBody OrganizationalStructure vo) {
        List<Department> list = departmentService.list(new QueryWrapper<Department>()
                .eq("site_id",vo.getId()));
        if (!list.isEmpty())
            throw new MyException("该站点绑定的部门未删除完，请删除完部门后再试！！！");
        List<EquipmentManagement> list1 = equipmentManagementService.list(new QueryWrapper<EquipmentManagement>().eq("site_id", vo.getId())
                .eq("examine", 1));
        if (!list1.isEmpty())
            throw new MyException("该站点绑定的设备未删除完，请删除完设备后再试！！！");
        User user = UserThreadLocal.get();
        vo.setDeleteExamine(0);
        vo.setDeleteAccountId(user.getId());
        vo.setDeleteAccountName(user.getUsername());
        vo.setDeleteAccountTime(DateTimeUtil.dqsj());
        organizationalStructureService.saveOrUpdate(vo);
        return ApiResult.success();
    }

    /**
     * 站点删除审核
     * @param vo
     * @return
     */
    @PostMapping("siteRemoveExamine")
    public ApiResult siteRemoveExamine(@RequestBody OrganizationalStructure vo) {
        if (vo.getDeleteExamine()==1){
            organizationalStructureService.removeById(vo);
            userService.remove(new QueryWrapper<User>().eq("site_id",vo.getId()));
        }
        else {
            OrganizationalStructure byId = organizationalStructureService.getById(vo);
            organizationalStructureService.huanyuan(byId);
        }
        return ApiResult.success();
    }

    /**
     * 站点负责人添加
     * @param vo
     * @return
     */
    @PostMapping("siteHeaderAdd")
    public ApiResult siteHeaderAdd(@RequestBody UserVo vo){
        userService.siteHeaderAdd(vo);
        return ApiResult.success();
    }

    /**
     * 站点负责人编辑
     * @param vo
     * @return
     */
    @PostMapping("siteHeaderUpdate")
    public ApiResult siteHeaderUpdate(@RequestBody UserVo vo){
        userService.siteHeaderUpdate(vo);
        return ApiResult.success();
    }

    /**
     *  站点负责人审核列表
     * @return
     */
    @PostMapping("siteHeaderExamineList")
    public ApiResult siteHeaderExamineList(@RequestBody PageVo vo){
        IPage<SiteHeaderToUser> page =  organizationalStructureService.siteHeaderExamineList(vo);
        return ApiResult.success(page);
    }

    /**
     * 站点负责人审核
     * @param vo
     * @return
     */
    @PostMapping("siteHeaderExamine")
    public ApiResult siteHeaderExamine(@RequestBody User vo){
        User user = UserThreadLocal.get();
        vo.setExaminePersonId(user.getId());
        vo.setExaminePersonName(user.getNickname());
        vo.setExamineTime(DateTimeUtil.dqsj());
        vo.setExaminePersonSignature(vo.getExaminePersonSignature());
        userService.saveOrUpdate(vo);
        return ApiResult.success();
    }

    /**
     * 站点负责人删除
     * @param vo
     * @return
     */
    @PostMapping("siteHeaderRemove")
    public ApiResult siteHeaderRemove(@RequestBody User vo){
        User byId = userService.getById(vo);
        List<User> list1 = userService.list(new QueryWrapper<User>().eq("structure_id", byId.getStructureId())
                .eq("examine", 1));
            OrganizationalStructure structure = organizationalStructureService.getById(byId.getStructureId());
            if (structure.getType()==5){

                if (list1.size()>1){
                    userService.removeById(vo);
                    return ApiResult.success();
                }
                List<OrganizationalStructure> list = organizationalStructureService.list(new QueryWrapper<OrganizationalStructure>()
                        .eq("parent_id", byId.getStructureId()));
                if (!list.isEmpty())
                    throw new MyException("该区级负责人下面还绑定了站点，请删除站点后再试！！！");
            }
        if (structure.getType()==6){
            if (list1.size()>1){
                userService.removeById(vo);
                return ApiResult.success();
            }
            List<Department> list = departmentService.list(new QueryWrapper<Department>()
                    .eq("site_id", byId.getStructureId()));
            if (!list.isEmpty())
                throw new MyException("该站点负责人唯一，并且该站点下面关联了部门，请删除所有部门后再试！！！");
            else
                userService.removeById(vo);
        }

            userService.removeById(vo);
            return ApiResult.success();


    }


    /**
     * 组织树查询
     * @param vo
     * @return
     */
    @PostMapping("trees")
    public ApiResult tree(@RequestBody PageVo vo){
        List<StructureTree> orgList = getOrgList(vo.getId(),vo.getType());
        return ApiResult.success(orgList);
    }

    /**
     * 以树形结构查询组织机构
     */
    public List<StructureTree> getOrgList(Long id,Integer type) {
        QueryWrapper<OrganizationalStructure> organizationLambdaQueryWrapper = new QueryWrapper<>();
        if (!Objects.isNull(type))
            organizationLambdaQueryWrapper.le("type", type);
        organizationLambdaQueryWrapper.eq("examine",1);
        List<OrganizationalStructure> structures = organizationalStructureService.list(organizationLambdaQueryWrapper);
       ArrayList<OrganizationalStructure> rootOrgList = new ArrayList<>();
        for (OrganizationalStructure organizationalStructure : structures) {
            List<User> list = userService.list(new QueryWrapper<User>()
                   .eq("structure_id", organizationalStructure.getId()));
            if (!list.isEmpty())
               rootOrgList.add(organizationalStructure);
       }
        List<StructureTree> organizationVOlist = new ArrayList<>();
        for (OrganizationalStructure temp : CollectionUtils.emptyIfNull(rootOrgList)) {
            StructureTree organizationVO = new StructureTree();
            BeanUtils.copyProperties(temp, organizationVO);
            organizationVOlist.add(organizationVO);
        }


        List<StructureTree> organizationVOresultList = new ArrayList<>();
        // 先找到所有的一级节点
        organizationVOlist.forEach(node->{
            int index = 1;
            if (!Objects.isNull(type))
                index += organizationVOlist.stream().filter(rootNode -> node.getParentId().equals(rootNode.getId())).count();
            else
                index += organizationVOlist.stream().filter(rootNode -> !node.getParentId().equals(id)).count();
            if(index == 1){ //如果没有与当前pId相等的orgId，则index仍然为1，意味着是一级节点，则将一级节点加入最后结果列表中
                if (!Objects.isNull(node.getNowId())){
                    Area byId = areaService.getById(node.getNowId());
                    node.setName(byId.getName());
                }
                organizationVOresultList.add(node);
            }
        });
        // 递归地为一级节点设置子节点
        organizationVOresultList.forEach(node->node.setChildren(childHandle(node.getId(), organizationVOlist)));
        return organizationVOresultList;
    }

    //递归地获取子节点
    private List<StructureTree> childHandle(Long orgId, List<StructureTree> list) {
        List<StructureTree> childList = new ArrayList<>();
        // 遍历所有节点，如果该节点的父类id等于orgId，则作为子节点加入当前节点中
        list.forEach(node->{
            if (node.getParentId().equals(orgId)) {
                childList.add(node);
            }
        });
        // 把子节点的孩子节点循环一遍
        childList.forEach(node->node.setChildren(childHandle(node.getId(), list)));
        if (childList.size() == 0) { return null; }
        return childList;
    }

    /**
     *  渠道商审核列表改
     * @return
     */
    @PostMapping("channelExamineListgai")
    public ApiResult channelExamineListgai(@RequestBody PageVo vo){
        IPage<UserToStructureModel> page =  organizationalStructureService.channelExamineListgai(vo);
        return ApiResult.success(page);
    }

    /**
     * 站点管理/站点审核列表/删除列表
     * @param vo
     * @return
     * state 0-站点管理  1-站点审核列表 2-删除列表
     */
    @PostMapping("siteList")
    public ApiResult siteListGai(@RequestBody PageVo vo) {
        IPage<OrganizationalStructure> page =  organizationalStructureService.siteListGai(vo);
        return ApiResult.success(page);
    }


    /**
     * 组织树查询-改
     * @param vo
     * @return
     */
    @PostMapping("tree")
    public ApiResult trees(@RequestBody PageVo vo){
        List<StructureTree> orgList = getOrgLists(vo.getId(),vo.getType());
        for (StructureTree structureTree : orgList) {
            if (!Objects.isNull(structureTree.getNowId())){
                Area byId = areaService.getById(structureTree.getNowId());
                structureTree.setName(byId.getName());
            }

        }
        return ApiResult.success(orgList);
    }


    /**
     * 以树形结构查询组织机构
     */
    public List<StructureTree> getOrgLists(Long id,Integer type) {
        QueryWrapper<OrganizationalStructure> organizationLambdaQueryWrapper = new QueryWrapper<>();
        if (!Objects.isNull(type))
            organizationLambdaQueryWrapper.le("type", type);
        organizationLambdaQueryWrapper.eq("examine",1);
        List<OrganizationalStructure> rootOrgList = organizationalStructureService.list(organizationLambdaQueryWrapper);
//        ArrayList<OrganizationalStructure> rootOrgList = new ArrayList<>();
////        for (OrganizationalStructure organizationalStructure : structures) {
////            List<User> list = userService.list(new QueryWrapper<User>()
////                    .eq("structure_id", organizationalStructure.getId()));
////            if (!list.isEmpty())
////                rootOrgList.add(organizationalStructure);
////        }

        List<StructureTree> organizationVOlist = new ArrayList<>();
        for (OrganizationalStructure temp : CollectionUtils.emptyIfNull(rootOrgList)) {
            StructureTree organizationVO = new StructureTree();
            BeanUtils.copyProperties(temp, organizationVO);
            organizationVOlist.add(organizationVO);
        }


        List<StructureTree> organizationVOresultList = new ArrayList<>();
        // 先找到所有的一级节点
        organizationVOlist.forEach(node->{
            int index = 1;
            if (!Objects.isNull(type))
                index += organizationVOlist.stream().filter(rootNode -> node.getParentId().equals(rootNode.getId())).count();
            else
                index += organizationVOlist.stream().filter(rootNode -> !node.getParentId().equals(id)).count();
            if(index == 1){ //如果没有与当前pId相等的orgId，则index仍然为1，意味着是一级节点，则将一级节点加入最后结果列表中
                if (!Objects.isNull(node.getNowId())){
                    Area byId = areaService.getById(node.getNowId());
                    node.setName(byId.getName());
                }
                organizationVOresultList.add(node);
            }
        });
        // 递归地为一级节点设置子节点
        organizationVOresultList.forEach(node->node.setChildren(childHandles(node.getId(), organizationVOlist)));
        return organizationVOresultList;
    }

    //递归地获取子节点
    private List<StructureTree> childHandles(Long orgId, List<StructureTree> list) {
        List<StructureTree> childList = new ArrayList<>();
        // 遍历所有节点，如果该节点的父类id等于orgId，则作为子节点加入当前节点中
        list.forEach(node->{
            if (node.getParentId().equals(orgId)) {
                if (!Objects.isNull(node.getNowId())){
                    if (node.getType().equals(2)) {
                        Area byId = areaService.getById(node.getNowId());
                        node.setName(byId.getName());
                    }
                    if (node.getType().equals(3)) {
                        Provinces byId =provincesMapper.selectOne(new QueryWrapper<Provinces>()
                                .eq("provinceid",node.getNowId()));
                        node.setName(byId.getProvince());
                    }
                    if (node.getType().equals(4)) {
                        Cities byId =citiesMapper.selectOne(new QueryWrapper<Cities>()
                                .eq("cityid",node.getNowId()));
                        node.setName(byId.getCity());
                    }
                    if (node.getType().equals(5)) {
                        Areas areas = areasMapper.selectOne(new QueryWrapper<Areas>()
                                .eq("areaid", node.getNowId()));
                        node.setName(areas.getArea());
                    }
                }
                childList.add(node);
            }
        });
        // 把子节点的孩子节点循环一遍
        childList.forEach(node->node.setChildren(childHandles(node.getId(), list)));
        if (childList.size() == 0) { return null; }
        return childList;
    }


    /***
     * 渠道商关联大区
     * @param vo
     * @return
     */
    @PostMapping("channelAdd")
    public ApiResult guanlian(@RequestBody OrganizationalStructure vo){
        organizationalStructureService.guanlian(vo);
        return ApiResult.success();
    }

    /**
     *  各级列表审核列表
     * @return
     */
    @PostMapping("channelExamineList")
    public ApiResult channelExamineListevery(@RequestBody PageVo vo){
        IPage<SiteHeaderToUser> page =  organizationalStructureService.channelExamineListevery(vo);
        return ApiResult.success(page);
    }

    /**
     * 测试添加大区慢
     * @param vo
     * @return
     */
    @PostMapping("channelAddCeshi")
    public ApiResult channelAddCeshi(@RequestBody OrganizationalStructure vo){
        organizationalStructureService.channelAddCeshi(vo);
        return ApiResult.success();
    }

    /**
     * 切换站点列表-只有站点负责人才有
     * @param
     * @return
     */
    @PostMapping("qhzd")
    public ApiResult qhzd(){
        User user = UserThreadLocal.get();
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone",user.getPhone());
        wrapper.eq("nickname",user.getNickname());
        //wrapper.isNull("department_id");
        wrapper.isNotNull("site_id");
        List<User> list = userService.list(wrapper);
        if (!list.isEmpty()){
            ArrayList<OrganizationalStructure> structures = new ArrayList<>();
            for (User user1 : list) {
                OrganizationalStructure byId = organizationalStructureService.getById(user1.getSiteId());
                if (!Objects.isNull(byId)&&byId.getType()==6){
                    byId.setId(user1.getId());
                    OrganizationalStructure chal = organizationalStructureService.getById(byId.getChannelId());
                    OrganizationalStructure region = organizationalStructureService.getById(byId.getRegionId());
                    OrganizationalStructure sheng = organizationalStructureService.getById(byId.getShengId());
                    OrganizationalStructure shi = organizationalStructureService.getById(byId.getShiId());
                    OrganizationalStructure qu = organizationalStructureService.getById(byId.getQuId());
                    byId.setChannelName(chal.getName());
                    byId.setRegionName(region.getName());
                    byId.setShengName(sheng.getName());
                    byId.setShiName(shi.getName());
                    byId.setQuName(qu.getName());
                    structures.add(byId);
                }

            }
            return ApiResult.success(structures);
        }
        return ApiResult.success();
    }

    @PostMapping("dl")
    public ApiResult dl(@RequestBody User vo){
        User user = userService.cxuser(vo.getId());
        String decoder = MD5Util.decoder(user.getPassword());
        vo.setUsername(user.getUsername());
        vo.setPassword(decoder);
        Map<String, Object> userinfo = userService.login(vo);
        return ApiResult.ok().data(userinfo);
    }

    /**
     * 开启关闭报警和阈值工单
     * @param vo
     * @return
     */
    @PostMapping("open")
    public ApiResult open(@RequestBody OrganizationalStructure vo){
        organizationalStructureService.saveOrUpdate(vo);
        return ApiResult.success();
    }
}

